﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using System.Windows.Forms;



namespace Cliente_Windows_Mobile
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == System.Windows.Forms.Keys.Up))
            {
                // Up
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Down))
            {
                // Down
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Left))
            {
                // Left
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Right))
            {
                // Right
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Enter))
            {
                // Enter
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void label1_ParentChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 formaSiguiente = new Form2();
            this.Hide(); //oculta la forma actual
            formaSiguiente.Show(); // muestra la forma2
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            //Usuario leido de BD
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            //Pass del usuario leida desde BD
        }

        public static void Main(string[] args)
        {
            byte[] bytes = new byte[1024];
            try
            {
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5050);
                Socket sender = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    sender.Connect(remoteEP);

                    Console.WriteLine("Socket connected to {0}",
                        sender.RemoteEndPoint.ToString());


                    //Recibe Bienvenida del servidor
                    byte[] recibido = Recibir(sender); //recibir
                    //deserializar el mensaje XML
                    Stream st = new MemoryStream(recibido);
                    Cliente.Mensaje msg = Cliente.Mensaje.Deserialize(st);
                    //String content = Encoding.UTF8.GetString(recibido);
                    st.Close();
                    //Console.WriteLine(content);
                    //Serializar el mensaje XML creando el archivo recibido+id.xml
                    Cliente.Mensaje m = new Cliente.Mensaje();
                    m.contenido = msg.contenido;
                    m.clientID = msg.clientID;
                    m.tipo = msg.tipo;
                    m.RSerialize();

                    Console.WriteLine("Recibido");

                    //Enviar

                    //Creando mensaje a enviar - Comando LIST
                    Cliente.Mensaje mensaje = new Cliente.Mensaje();
                    mensaje.contenido = "List"; //id del video
                    mensaje.tipo = Cliente.Mensaje.MsgType.LIST;
                    mensaje.clientID = msg.clientID;
                    mensaje.Serialize();//Serializar el mensaje

                    SendMsg(sender, mensaje);//Enviar mensaje al servidor		
                    Console.WriteLine("Enviado Solicitud Video");

                    //Recibiendo el listado
                    recibido = Recibir(sender);
                    FileStream fs = new FileStream(Directory.GetCurrentDirectory() + "/xml/listado.xml", FileMode.Create);
                    fs.Write(recibido, 0, recibido.Length);
                    fs.Close();
                    List<Cliente.VideoList> listado = DeserializeList(Directory.GetCurrentDirectory() + "/xml/listado.xml", msg.clientID);
                    foreach (Cliente.VideoList video in listado)
                    {
                        video.show();
                    }
                    //Finalizar coneccion se eliminan los archivos del directorio xml/
                    foreach (string f in Directory.GetFiles(Directory.GetCurrentDirectory() + "/xml/"))
                    {
                        File.Delete(f);
                    }
                    // Release the socket.
                    sender.Shutdown(SocketShutdown.Both);
                    sender.Close();

                }
                catch (ArgumentNullException ane)
                {
                    Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
                }
                catch (SocketException se)
                {
                    Console.WriteLine("SocketException : {0}", se.ToString());
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unexpected exception : {0}", e.ToString());
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            //MainClass.StartClient();
        }

        private static void SendMsg(Socket socket, Cliente.Mensaje mensaje)
        {
			mensaje.Serialize();
			
			FileStream fs = new FileStream(mensaje.getFile(),FileMode.Open,FileAccess.Read,FileShare.Read);
            byte[] video = ReadFully(fs);
			int total = 0;
			int size = video.Length;				
			int dataleft = size;
			int sent;
			
			byte[] datasize = new byte[4];
			datasize        = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(size));
			sent            = socket.Send(datasize);
			while(total < size){
				sent  = socket.Send(video,total,dataleft,SocketFlags.None);
				total+= sent;
				dataleft-= sent;
			}
		}

        private static byte[] ReadFully(FileStream fs)
        {
            throw new NotImplementedException();
        }

		private static byte[] Recibir(Socket s){
			int total = 0;
            int recv;
            byte[] datasize = new byte[4];
			
            recv = s.Receive(datasize, 0, 4, 0);
			int size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(datasize, 0));
			
            int dataleft = size;
            byte[] data = new byte[size];
            while (total < size)
            {
                recv = s.Receive(data, total, dataleft, 0);
                if (recv == 0)
                {
                    break;
                }
                total += recv;
                dataleft -= recv;
            }
            return data;
        }
				
		// Metodo para deserializar un archivo XML de tipo Listado de video
		private static List<Cliente.VideoList> DeserializeList(String archivo, Guid id){
   			XmlSerializer deserializer = new XmlSerializer(typeof(List<Cliente.VideoList>));
   			TextReader textReader = new StreamReader(archivo);
   			List<Cliente.VideoList> listado  = (List<Cliente.VideoList>)deserializer.Deserialize(textReader);
   			textReader.Close();	
   			return listado;
		}//DeserializeList

    }
}